package com.zbkj.service.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.constants.OrderConstants;
import com.zbkj.common.constants.OrderStatusConstants;
import com.zbkj.common.constants.ProductConstants;
import com.zbkj.common.model.merchant.MerchantAddress;
import com.zbkj.common.model.order.Order;
import com.zbkj.common.model.order.OrderDetail;
import com.zbkj.common.model.traceable.TraceableGroup;
import com.zbkj.common.model.traceable.TraceableOrderDetail;
import com.zbkj.common.model.user.User;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.*;
import com.github.pagehelper.PageHelper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zbkj.common.exception.AppException;

import com.zbkj.common.response.*;
import com.zbkj.common.result.CommonResultCode;
import com.zbkj.common.model.traceable.TraceableOrder;
import com.zbkj.common.utils.CrmebUtil;
import com.zbkj.service.dao.TraceableOrderDao;
import com.zbkj.service.service.*;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zbkj.service.util.BrandUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
* @author dazongzi
* @description TraceableOrderServiceImpl 接口实现
* @date 2025-07-10
*/
@Service
public class TraceableOrderServiceImpl extends ServiceImpl<TraceableOrderDao, TraceableOrder> implements TraceableOrderService {

    @Resource
    private TraceableOrderDao dao;
    @Autowired
    private TraceableOrderDetailService traceableOrderDetailService;
    @Autowired
    private UserService userService;

    @Autowired
    private MerchantService merchantService;

    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private OrderStatusService orderStatusService;
    @Autowired
    private TraceableGroupService traceableGroupService;
    @Autowired
    private EmployeeAddressService employeeAddressService;

    @Override
    public Boolean create(TraceableOrderSaveRequest traceableOrderSaveRequest) {
        TraceableOrder traceableOrder = new TraceableOrder();
        BeanUtils.copyProperties(traceableOrderSaveRequest, traceableOrder, "id");
        boolean save = save(traceableOrder);
        if (!save) {
            throw new AppException(CommonResultCode.VALIDATE_FAILED, "添加失败");
        }
        return save;
    }

    /**
     * 分页查询溯源订单表
     *
     * @param request          请求参数
     * @param pageParamRequest 分页类参数
     * @return List<TraceableOrder>
     * @author dazongzi
     * @since 2025-07-10
     */
    @Override
    public List<TraceableOrderPageDataResponse> getList(TraceableOrderSearchRequest request, PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        //带 ShortplayItems 类的多条件查询
        LambdaQueryWrapper<TraceableOrder> lambdaQueryWrapper = Wrappers.lambdaQuery();

        if (StrUtil.isNotBlank(request.getOrderNo())) {
            lambdaQueryWrapper.eq(TraceableOrder::getOrderNo, request.getOrderNo().trim());
        }

        if (ObjectUtil.isNotEmpty(request.getOrderStatus())) {
            lambdaQueryWrapper.eq(TraceableOrder::getOrderStatus, request.getOrderStatus());
        }

        if (ObjectUtil.isNotEmpty(request.getPayChannel())) {
            lambdaQueryWrapper.eq(TraceableOrder::getPayChannel, request.getPayChannel());
        }

        if (ObjectUtil.isNotEmpty(request.getPayType())) {
            lambdaQueryWrapper.eq(TraceableOrder::getPayType, request.getPayType());
        }

        if (StrUtil.isNotBlank(request.getMerchantName())) {
            lambdaQueryWrapper.like(TraceableOrder::getMerchantName, request.getMerchantName().trim());
        }
        lambdaQueryWrapper.eq(TraceableOrder::getIsDel, false);
        lambdaQueryWrapper.orderByDesc(TraceableOrder::getCreateTime);
        List<TraceableOrder> traceableOrders = dao.selectList(lambdaQueryWrapper);
        // 添加活动状态
        List<TraceableOrderPageDataResponse> traceableOrderResponses = new ArrayList<>();

        traceableOrders.stream().forEach(x->{
            TraceableOrderPageDataResponse traceableOrderResponse = new TraceableOrderPageDataResponse();
            BeanUtils.copyProperties(x, traceableOrderResponse);
            traceableOrderResponses.add(traceableOrderResponse);
        });
        return traceableOrderResponses;
    }


    /**
     * 分页查询溯源订单表
     *
     * @param request          请求参数
     * @param pageParamRequest 分页类参数
     * @return List<TraceableOrder>
     * @author dazongzi
     * @since 2025-07-10
     */
    @Override
    public List<TraceableOrderPageDataBrandResponse> getListBrand(TraceableOrderSearchBrandRequest request, PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        //带 ShortplayItems 类的多条件查询
        LambdaQueryWrapper<TraceableOrder> lambdaQueryWrapper = Wrappers.lambdaQuery();

        if (StrUtil.isNotBlank(request.getOrderNo())) {
            lambdaQueryWrapper.eq(TraceableOrder::getOrderNo, request.getOrderNo().trim());
        }

        if (ObjectUtil.isNotEmpty(request.getOrderStatus())) {
            lambdaQueryWrapper.eq(TraceableOrder::getOrderStatus, request.getOrderStatus());
        }

        if (ObjectUtil.isNotEmpty(request.getPayChannel())) {
            lambdaQueryWrapper.eq(TraceableOrder::getPayChannel, request.getPayChannel());
        }

        if (ObjectUtil.isNotEmpty(request.getPayType())) {
            lambdaQueryWrapper.eq(TraceableOrder::getPayType, request.getPayType());
        }

        if (StrUtil.isNotBlank(request.getMerchantName())) {
            lambdaQueryWrapper.like(TraceableOrder::getMerchantName, request.getMerchantName().trim());
        }
        lambdaQueryWrapper.eq(TraceableOrder::getBrandId, BrandUtil.getBrandIdByUrl());
        lambdaQueryWrapper.eq(TraceableOrder::getIsDel, false);
        lambdaQueryWrapper.orderByDesc(TraceableOrder::getCreateTime);
        List<TraceableOrder> traceableOrders = dao.selectList(lambdaQueryWrapper);
        // 添加活动状态
        List<TraceableOrderPageDataBrandResponse> traceableOrderResponses = new ArrayList<>();

        traceableOrders.stream().forEach(x->{
            TraceableOrderPageDataBrandResponse traceableOrderResponse = new TraceableOrderPageDataBrandResponse();
            BeanUtils.copyProperties(x, traceableOrderResponse);
            traceableOrderResponses.add(traceableOrderResponse);
        });
        return traceableOrderResponses;
    }



    private TraceableOrder getByIdException(Integer id) {
        TraceableOrder traceableOrder = getById(id);
        if (ObjectUtil.isNull(traceableOrder)) {
            throw new AppException("溯源订单表不存在");
        }
        if (traceableOrder.getIsDel()) {
            throw new AppException("溯源订单表不存在");
        }
        return traceableOrder;
    }

    /**
    * 批量删除
    * @param idList
    * @return
    */
    @Override
    public boolean batchDelete(List<Integer> idList) {
    LambdaUpdateWrapper<TraceableOrder> luw = Wrappers.lambdaUpdate();
        luw.set(TraceableOrder::getIsDel, true);
        luw.in(TraceableOrder::getId, idList);
        boolean update = update(luw);
        if (!update) {
            throw new AppException(CommonResultCode.ERROR.setMessage("批量删除溯源订单表失败"));
        }
        return true;
    }

    /**
    * 查询溯源套餐表详情
    * @param id
    * @return
    */
    @Override
    public TraceableOrderDetailResponse getDetails(Integer id) {
        TraceableOrder monitorOrder = getByIdException(id);
        TraceableOrderDetailResponse response = new TraceableOrderDetailResponse();
        BeanUtils.copyProperties(monitorOrder, response);
        // 明细
        List<TraceableOrderDetail> list = traceableOrderDetailService.getListByOrderId(monitorOrder.getId());
        if (CollUtil.isNotEmpty(list)) {
            List<TraceableOrderDetailItemResponse> responseList = new ArrayList<>();
            for (TraceableOrderDetail x : list) {
                TraceableOrderDetailItemResponse itemResponse = new TraceableOrderDetailItemResponse();
                BeanUtils.copyProperties(x, itemResponse);
                responseList.add(itemResponse);
            }
            response.setDetailList(responseList);
        }
        return response;
    }

    @Override
    public PageInfo<TraceableOrderFrontSearchResponse> getListFront(TraceableOrderFrontSearchRequest request, PageParamRequest pageParamRequest) {
        User user = userService.getInfo();
        Page<TraceableOrder> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        //带 ShortplayItems 类的多条件查询
        LambdaQueryWrapper<TraceableOrder> lambdaQueryWrapper = Wrappers.lambdaQuery();

        if (StrUtil.isNotBlank(request.getOrderNo())) {
            lambdaQueryWrapper.eq(TraceableOrder::getOrderNo, request.getOrderNo().trim());
        }

        if (ObjectUtil.isNotEmpty(request.getOrderStatus())) {
            lambdaQueryWrapper.eq(TraceableOrder::getOrderStatus, request.getOrderStatus());
        }

        if (ObjectUtil.isNotEmpty(request.getPayChannel())) {
            lambdaQueryWrapper.eq(TraceableOrder::getPayChannel, request.getPayChannel());
        }

        if (ObjectUtil.isNotEmpty(request.getPayType())) {
            lambdaQueryWrapper.eq(TraceableOrder::getPayType, request.getPayType());
        }

        if (StrUtil.isNotBlank(request.getMerchantName())) {
            lambdaQueryWrapper.like(TraceableOrder::getMerchantName, request.getMerchantName().trim());
        }

        lambdaQueryWrapper.eq(TraceableOrder::getUserId, user.getId());
        lambdaQueryWrapper.eq(TraceableOrder::getIsDel, false);
        lambdaQueryWrapper.orderByDesc(TraceableOrder::getCreateTime);
        List<TraceableOrder> shortplayItemss = dao.selectList(lambdaQueryWrapper);
        if (ObjectUtil.isEmpty(shortplayItemss)) {
            return CommonPage.copyPageInfo(page, new ArrayList<>());
        }
        // 添加活动状态
        List<TraceableOrderFrontSearchResponse> list = new ArrayList<>();

        shortplayItemss.stream().forEach(x->{
            TraceableOrderFrontSearchResponse response = new TraceableOrderFrontSearchResponse();
            BeanUtils.copyProperties(x, response);
            list.add(response);
        });
        return CommonPage.copyPageInfo(page, list);
    }

    @Override
    public OrderNoResponse createOrder(TraceableOrderFrontSaveRequest request) {
        User user = userService.getInfo();
        TraceableOrder monitorOrder = new TraceableOrder();
        monitorOrder.setUserId(user.getId());
        BigDecimal productPrice = BigDecimal.ZERO;
        List<TraceableOrderDetail> list = new ArrayList<>();
        List<String> productNameList = new ArrayList<>();

        MerchantAddress merchantAddress = employeeAddressService.getById(request.getAddressId());
        if (ObjectUtil.isNull(merchantAddress)) {
            throw new AppException(CommonResultCode.VALIDATE_FAILED, "商户地址不存在");
        }

        for (TraceableOrderDetailFrontSaveRequest traceableOrderDetailFrontSaveRequest : request.getDetailList()) {
            TraceableGroup platformTraceableGroup = traceableGroupService.getPlatformGroup(traceableOrderDetailFrontSaveRequest.getTraceableId());
            if (ObjectUtil.isNull(platformTraceableGroup)) {
                throw new AppException(CommonResultCode.VALIDATE_FAILED, "溯源套餐已在平台下架");
            }
            TraceableOrderDetail traceableOrderDetail = new TraceableOrderDetail();

            TraceableGroup traceableGroup = traceableGroupService.getBrandGroup(traceableOrderDetailFrontSaveRequest.getTraceableId());
            if (ObjectUtil.isNotNull(traceableGroup)) {
                productPrice = productPrice.add(traceableGroup.getPrice().multiply(new BigDecimal(traceableOrderDetailFrontSaveRequest.getPayNum().toString())));
                String productName = traceableGroup.getName() + "/" + traceableOrderDetailFrontSaveRequest.getPayNum();
                productNameList.add(productName);
                traceableOrderDetail.setGroupName(traceableGroup.getName());
            } else {
                // 平台
                productPrice = productPrice.add(platformTraceableGroup.getPrice().multiply(new BigDecimal(traceableOrderDetailFrontSaveRequest.getPayNum().toString())));
                String productName = platformTraceableGroup.getName() + "/" + traceableOrderDetailFrontSaveRequest.getPayNum();
                productNameList.add(productName);
                traceableOrderDetail.setGroupName(platformTraceableGroup.getName());
            }
            traceableOrderDetail.setTraceableId(traceableOrderDetailFrontSaveRequest.getTraceableId());
            traceableOrderDetail.setPayNum(traceableOrderDetailFrontSaveRequest.getPayNum());
            list.add(traceableOrderDetail);
        }
        monitorOrder.setProTotalPrice(productPrice);
        // 四舍五入
        monitorOrder.setProTotalPrice(monitorOrder.getProTotalPrice().setScale(2, BigDecimal.ROUND_UP));
        monitorOrder.setTotalPrice(monitorOrder.getProTotalPrice());

        monitorOrder.setPayPrice(monitorOrder.getProTotalPrice());
        monitorOrder.setProductName(CollUtil.join(productNameList, ","));
        monitorOrder.setBrandId(BrandUtil.getBrandIdByUrl());
        monitorOrder.setReceiverName(merchantAddress.getReceiverName());
        monitorOrder.setReceiverPhone(merchantAddress.getReceiverPhone());
        monitorOrder.setDetail(merchantAddress.getDetail());

        Order order = new Order();
        if (user.getBrandId() != 0) {
            String orderNo = CrmebUtil.getOrderNo(OrderConstants.ORDER_PREFIX_BRAND);
            order.setOrderNo(orderNo);
            order.setLevel(OrderConstants.ORDER_LEVEL_BRAND);
        }else{
            String orderNo = CrmebUtil.getOrderNo(OrderConstants.ORDER_PREFIX_PLATFORM);
            order.setOrderNo(orderNo);
            order.setLevel(OrderConstants.ORDER_LEVEL_PLATFORM);
        }
        // 因为订单属于平台订单，所以这里不设置商户id
        order.setMerId(0);
        order.setUid(user.getId());
        order.setTotalNum(1);
        order.setTotalPostage(BigDecimal.ZERO);
        order.setSvipDiscountPrice(BigDecimal.ZERO);
        order.setTotalPrice(monitorOrder.getPayPrice());
        order.setCouponPrice(BigDecimal.ZERO);
        order.setUseIntegral(0);
        order.setIntegralPrice(BigDecimal.ZERO);
        order.setPayPrice(monitorOrder.getPayPrice());
        order.setPayPostage(BigDecimal.ZERO);
        order.setPaid(false);
        order.setCancelStatus(OrderConstants.ORDER_CANCEL_STATUS_NORMAL);
        // 溯源套餐订单
        order.setType(OrderConstants.ORDER_TYPE_TRACEABLE);
        order.setMerCouponPrice(BigDecimal.ZERO);
        order.setPlatCouponPrice(BigDecimal.ZERO);
        order.setIsSvip(user.getIsPaidMember());

        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderNo(order.getOrderNo());
        // 因为监控流量充值属于平台订单，所以这里不设置商户id
        orderDetail.setMerId(0);
        orderDetail.setUid(user.getId());
        orderDetail.setProductId(0);
        orderDetail.setProductName(monitorOrder.getProductName());
        orderDetail.setAttrValueId(0);
        orderDetail.setSku("溯源套餐");
        orderDetail.setPrice(monitorOrder.getPayPrice());
        orderDetail.setPayNum(1);
        orderDetail.setWeight(BigDecimal.ZERO);
        orderDetail.setVolume(BigDecimal.ZERO);
        orderDetail.setProductType(ProductConstants.PRODUCT_TYPE_TRACEABLE);
        orderDetail.setSubBrokerageType(0);
        orderDetail.setBrokerage(0);
        orderDetail.setBrokerageTwo(0);
        orderDetail.setFreightFee(BigDecimal.ZERO);
        orderDetail.setUseIntegral(0);
        orderDetail.setIntegralPrice(BigDecimal.ZERO);
        orderDetail.setPayPrice(monitorOrder.getPayPrice());

        orderDetail.setIsSvip(order.getIsSvip());
        orderDetail.setIsPaidMemberProduct(false);
        orderDetail.setVipPrice(BigDecimal.ZERO);

        orderDetail.setMerCouponPrice(BigDecimal.ZERO);
        orderDetail.setPlatCouponPrice(BigDecimal.ZERO);
        orderDetail.setCouponPrice(BigDecimal.ZERO);
        orderDetail.setImage("");
        orderDetail.setPrice(productPrice);

        monitorOrder.setPrice(productPrice);
        monitorOrder.setOrderNo(order.getOrderNo());
        // 0待支付 1已支付
        monitorOrder.setOrderStatus(0);
        monitorOrder.setCreateTime(new Date());
        monitorOrder.setType(1);

        this.save(monitorOrder);

        orderService.save(order);
        for (TraceableOrderDetail traceableOrderDetail : list) {
            traceableOrderDetail.setOrderId(order.getId());
            traceableOrderDetail.setOrderNo(order.getOrderNo());
        }
        traceableOrderDetailService.saveBatch(list);
        orderDetailService.save(orderDetail);

        // 生成订单日志
        orderStatusService.createLog(order.getOrderNo(), OrderStatusConstants.ORDER_STATUS_CREATE, OrderStatusConstants.ORDER_LOG_MESSAGE_CREATE);

        OrderNoResponse response = new OrderNoResponse();
        response.setOrderNo(order.getOrderNo());
        response.setPayPrice(order.getPayPrice());
        response.setOrderType(OrderConstants.ORDER_TYPE_MONITOR_REG);
        return response;
    }

    @Override
    public void callBack(String orderNo) {
        TraceableOrder traceableOrder = getByOrderNo(orderNo);
        Order order = orderService.getByOrderNo(orderNo);
        traceableOrder.setThirdOrderNo(order.getOutTradeNo());
        traceableOrder.setPayType(order.getPayType());
        traceableOrder.setPayChannel(order.getPayChannel());
        // 0-待支付 1-已支付
        if (Objects.equals(order.getPaid(), true)) {
            traceableOrder.setOrderStatus(1);
        } else {
            traceableOrder.setOrderStatus(0);
        }
        updateById(traceableOrder);
    }

    @Override
    public TraceableOrderDetailFrontResponse getDetailsH5(Integer id) {
        TraceableOrder monitorOrder = getByIdException(id);
        TraceableOrderDetailFrontResponse response = new TraceableOrderDetailFrontResponse();
        BeanUtils.copyProperties(monitorOrder, response);
        // 明细
        List<TraceableOrderDetail> list = traceableOrderDetailService.getListByOrderId(monitorOrder.getId());
        if (CollUtil.isNotEmpty(list)) {
            List<TraceableOrderDetailItemFrontResponse> responseList = new ArrayList<>();
            for (TraceableOrderDetail x : list) {
                TraceableOrderDetailItemFrontResponse itemResponse = new TraceableOrderDetailItemFrontResponse();
                BeanUtils.copyProperties(x, itemResponse);
                responseList.add(itemResponse);
            }
            response.setDetailList(responseList);
        }
        return response;
    }

    @Override
    public TraceableOrderDetailBrandResponse getDetailsBrand(Integer id) {
        TraceableOrder monitorOrder = getByIdException(id);
        TraceableOrderDetailBrandResponse response = new TraceableOrderDetailBrandResponse();
        BeanUtils.copyProperties(monitorOrder, response);
        // 明细
        List<TraceableOrderDetail> list = traceableOrderDetailService.getListByOrderId(monitorOrder.getId());
        if (CollUtil.isNotEmpty(list)) {
            List<TraceableOrderDetailItemResponse> responseList = new ArrayList<>();
            for (TraceableOrderDetail x : list) {
                TraceableOrderDetailItemResponse itemResponse = new TraceableOrderDetailItemResponse();
                BeanUtils.copyProperties(x, itemResponse);
                responseList.add(itemResponse);
            }
            response.setDetailList(responseList);
        }
        return response;
    }

    private TraceableOrder getByOrderNo(String orderNo) {
        LambdaQueryWrapper<TraceableOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(TraceableOrder::getOrderNo, orderNo);
        lqw.eq(TraceableOrder::getIsDel, false);
        lqw.orderByDesc(TraceableOrder::getCreateTime);
        lqw.last(" limit 1");
        return dao.selectOne(lqw);
    }

}

